/*
 * @Author: your name
 * @Date: 2022-05-01 06:35:50
 * @LastEditTime: 2022-05-09 11:43:29
 * @LastEditors: daniel_du dll_2018@126.com
 * @Description: 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 * @FilePath: /safe_transmission_platform/src/myrsa.h
 */
#ifndef __DANIEL_MYRSA_H__
#define __DANIEL_MYRSA_H__

#include <openssl/rsa.h>
#include <iostream>
#include <memory>
#include <openssl/pem.h>
namespace daniel
{
    // rsa非对称加密封装类，主要封装密钥生成、加密和签名功能
    class MyRsa
    {
    public:
        using ptr = std::shared_ptr<MyRsa>;
        enum OperationType
        {
            LoadPublicKey = 0,
            LoadPrivateKey,
            GenerateKeys
        };
        enum SignType
        {
            SignMD5=NID_md5,
            SignSHA1=NID_sha1,
            SignSHA224=NID_sha224,
            SignSHA256=NID_sha256,
            SignSHA384=NID_sha384,
            SignSHA512=NID_sha512,
        };
        //构造功能和析构功能
        MyRsa(OperationType type, const std::string &keyStr = "",bool isLoadFile=true);
        ~MyRsa();
        //密钥生成功能  指定密钥的长度
        OperationType getType() const {return m_type;}
        void generateKeys(int bits);
        //密钥写入文件功能
        void saveKeysToFile(const std::string &publicKeyFile, const std::string &privateKeyFile);
        //私钥、公钥加密功能
        void publicEncrypt(int flen, const unsigned char *from,unsigned char *to, int padding = RSA_PKCS1_PADDING);
        void publicEncrypt(const std::string& from, std::string& to);
        void privateEncrypt(int flen, const unsigned char *from,unsigned char *to, int padding = RSA_PKCS1_PADDING);
        void privateEncrypt(const std::string& from, std::string& to);
        //私钥、公钥解密功能
        void publicDecrypt(int flen, const unsigned char *from,unsigned char *to, int padding = RSA_PKCS1_PADDING);
        void publicDecrypt(const std::string& from, std::string& to);
        void privateDecrypt(int flen, const unsigned char *from,unsigned char *to, int padding = RSA_PKCS1_PADDING);
        void privateDecrypt(const std::string& from, std::string& to);
        //使用私钥签名   
        bool RSA_sign(SignType type, const unsigned char *m, unsigned int m_length,unsigned char *sigret, unsigned int *siglen);
        bool RSA_sign(SignType type, const std::string& data, std::string& retData);
        bool RSA_sign_extend(SignType type, const std::string& data, std::string& retData);
        bool RSA_hashsign(SignType type, const std::string& data, std::string& retData);

        //使用公钥验证签名
        bool RSA_verify(SignType type, const unsigned char *m, unsigned int m_length,const unsigned char *sigbuf, unsigned int siglen);
        //msgStr原始数据  sigStr签名之后的数据
        bool RSA_verify(SignType type, const std::string& msgStr,const std::string& sigStr);
        bool RSA_verify_extend(SignType type, const std::string& msgStr,const std::string& sigStr);
        bool RSA_hashverify(SignType type, const std::string& msgStr, const std::string& sigStr);
        RSA* getTotalKey() const {return m_totalKey;}
        RSA* getPublicKey() const {return m_publicKey;}
        RSA* getPrivateKey() const {return m_privateKey;}
        //base64的编解码操作
        static std::string base64Encode(const std::string& msg);
        static std::string base64Decode(const std::string& encodeMsg);
        //增加秘钥写方法，将秘钥写入文件或者内存
        
    private:
        void loadKeyFromFile(const std::string &keyStr,bool isFile);
    private:
        OperationType m_type;
        RSA *m_totalKey;
        RSA *m_publicKey;
        RSA *m_privateKey;
    };
} // namespace daniel

#endif